package com.meeting.meetingroom_api.controller;

import com.meeting.meetingroom_api.dto.BookingCreateDto;
import com.meeting.meetingroom_api.dto.BookingDto;
import com.meeting.meetingroom_api.dto.BookingQueryDto;
import com.meeting.meetingroom_api.enums.BookingStatus;
import com.meeting.meetingroom_api.service.BookingService;
import com.meeting.meetingroom_api.service.BookingCheckService;
import com.meeting.meetingroom_api.security.UserDetailsImpl;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
//TODO:支付超时，会议室变空闲（定时器）,待深度测试
@RestController
@RequestMapping("/api/bookings")
public class BookingController {

    private final BookingService bookingService;
    private final BookingCheckService bookingCheckService;

    @Autowired
    public BookingController(BookingService bookingService, BookingCheckService bookingCheckService) {
        this.bookingService = bookingService;
        this.bookingCheckService = bookingCheckService;
    }

    /**
     * 创建预订订单：先查询时间是否与已有订单的时间冲突
     * 会议室锁定，支付后为已预订
     */
    //已测试
    @PreAuthorize("hasRole('CUSTOMER')")
    @PostMapping
    public ResponseEntity<BookingDto> createBooking(
            @Valid @RequestBody BookingCreateDto createDto,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.createBooking(createDto, currentUser.getId());
        return new ResponseEntity<>(booking, HttpStatus.CREATED);
    }

    /**
     * 获取单个订单详情
     */
    @GetMapping("/{bookingId}")
    public ResponseEntity<BookingDto> getBookingById(
            @PathVariable Integer bookingId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.getBookingById(bookingId);
        return ResponseEntity.ok(booking);
    }

    /**
     * 分页查询预订，支持多种过滤条件
     * 
     * 支持的查询参数：
     * - roomId: 会议室ID
     * - customerId: 客户ID  
     * - status: 单个预订状态
     * - statusList: 多个预订状态（用逗号分隔）
     * - startDatetime/desiredStartTime: 查询时间范围的开始时间
     * - endDatetime/desiredEndTime: 查询时间范围的结束时间
     * - includeCompleted: 是否包含已完成的预订
     * 
     * 时间查询示例：
     * GET /api/bookings?startDatetime=2024-01-15T10:00:00&endDatetime=2024-01-15T12:00:00
     * GET /api/bookings?desiredStartTime=2024-01-15T10:00:00&desiredEndTime=2024-01-15T12:00:00
     */
    @GetMapping
    public ResponseEntity<Page<BookingDto>> findBookings(
            BookingQueryDto queryDto,
            @PageableDefault(size = 10) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.findBookings(queryDto, pageable);
        return ResponseEntity.ok(bookings);
    }

    /**
     * 客户分页查询自己的订单，可以传入订单状态
     */
    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/my-bookings")
    public ResponseEntity<Page<BookingDto>> getMyBookings(@RequestParam BookingStatus status,
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @PageableDefault(size = 10, sort = "startDatetime", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.getBookingsByCustomerId(status,currentUser.getId(), pageable);
        return ResponseEntity.ok(bookings);
    }
    /**
     * 客户分页查询已完成（BookingStatus.completed,BookingStatus.cancelled_by_customer
     *                 ,BookingStatus.cancelled_payment_timeout）的订单.
     */
    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/myCompleted")
    public ResponseEntity<Page<BookingDto>> getMyCompletedBookings(
                                                          @AuthenticationPrincipal UserDetailsImpl currentUser,
                                                          @PageableDefault(size = 10, sort = "startDatetime", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.getCompletedBookings(currentUser.getId(), pageable);
        return ResponseEntity.ok(bookings);
    }
    /**
     * 分页查询客户提交取消预订的订单
     */
    @PreAuthorize("hasRole('CUSTOMER')")
    @GetMapping("/my-cancellable-bookings")
    public ResponseEntity<Page<BookingDto>> getMyCancellableBookings(
            @AuthenticationPrincipal UserDetailsImpl currentUser,
            @PageableDefault(size = 10, sort = "startDatetime", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.getCancellableBookingsByCustomerId(currentUser.getId(), pageable);
        return ResponseEntity.ok(bookings);
    }

    /**
     * 员工确认客户开始会议
     */
    //已测试
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{bookingId}/check-in")
    public ResponseEntity<BookingDto> checkIn(
            @PathVariable Integer bookingId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.checkIn(bookingId, currentUser.getId());
        return ResponseEntity.ok(booking);
    }

    /**
     * 员工确认客户离场，查看会议室状态，修改会议室状态为空闲（roomConditionNotes为空）或维修（roomConditionNotes不为空）
     */
    //已测试
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{bookingId}/check-out")
    public ResponseEntity<BookingDto> checkOut(
            @PathVariable Integer bookingId,
            String roomConditionNotes,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.checkOut(bookingId, currentUser.getId(), roomConditionNotes);
        return ResponseEntity.ok(booking);
    }

    /**
     * 设置会议室状态为维修中（维修备注：maintenanceNotes）
     */
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{bookingId}/maintenance")
    public ResponseEntity<BookingDto> setRoomMaintenance(
            @PathVariable Integer bookingId,
            @RequestParam String maintenanceNotes,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.setRoomMaintenance(bookingId, currentUser.getId(), maintenanceNotes);
        return ResponseEntity.ok(booking);
    }

    /**
     * 员工确认会议室已完成维修，会议室改为空闲
     */
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{bookingId}/complete-maintenance")
    public ResponseEntity<BookingDto> completeMaintenance(
            @PathVariable Integer bookingId,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingService.completeMaintenance(bookingId, currentUser.getId());
        return ResponseEntity.ok(booking);
    }

    /**
     * 强制设置会议室为维护状态（即使后续有预订）
     */
    @PreAuthorize("hasAnyRole('EMPLOYEE', 'ADMIN')")
    @PostMapping("/{bookingId}/force-maintenance")
    public ResponseEntity<BookingDto> forceSetMaintenance(
            @PathVariable Integer bookingId,
            @RequestParam String maintenanceNotes,
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        BookingDto booking = bookingCheckService.forceSetMaintenance(bookingId, currentUser.getId(), maintenanceNotes);
        return ResponseEntity.ok(booking);
    }

    // @PreAuthorize("hasAnyRole('ADMIN', 'EMPLOYEE')")

    @GetMapping("/customer/{customerId}")
    public ResponseEntity<Page<BookingDto>> getBookingsByCustomerId(
            @PathVariable Integer customerId,
            @PageableDefault(size = 10, sort = "createdAt", direction = org.springframework.data.domain.Sort.Direction.DESC) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.getBookingsByCustomerId(null,customerId, pageable);
        return ResponseEntity.ok(bookings);
    }

    // @PreAuthorize("hasAnyRole('ADMIN', 'EMPLOYEE')")
    @GetMapping("/room/{roomId}")
    public ResponseEntity<Page<BookingDto>> getBookingsByRoomId(
            @PathVariable Integer roomId,
            @PageableDefault(size = 10, sort = "createdAt", direction = org.springframework.data.domain.Sort.Direction.DESC) Pageable pageable) {
        Page<BookingDto> bookings = bookingService.getBookingsByRoomId(roomId, pageable);
        return ResponseEntity.ok(bookings);
    }

    //查询被预定的或使用中的会议室的订单信息
//    @GetMapping("/{roomId}/detail")
//    public ResponseEntity<BookingDto> getBookingByRoomId(@PathVariable Integer roomId) {
//        BookingDto bookings = bookingService.getBookingByActiveRoomId(roomId);
//        return ResponseEntity.ok(bookings);
//    }

    //客户取消待支付的订单：
    @PutMapping("/cancelPendingPay/{bookingId}")
    public ResponseEntity<BookingDto> cancelPendingPay(@PathVariable Integer bookingId) {
        BookingDto bookings = bookingService.cancelPendingPay(bookingId);
        return ResponseEntity.ok(bookings);
    }
    // @PreAuthorize("hasAnyRole('ADMIN', 'EMPLOYEE')")
    // 业务逻辑有bug待解决（过滤的时候调用的错误的持久层），而且这个接口应该没有必要,订单的状态不是主动改变的。
    // 应该可以保留业务方法，在员工处理退款的时候，改变取消预订表的同时改变订单表的状态。
    // @PatchMapping("/{bookingId}/status")
    // public ResponseEntity<BookingDto> updateBookingStatus(@PathVariable Integer bookingId,
    //                                                       @RequestParam BookingStatus status,
    //                                                       @AuthenticationPrincipal UserDetailsImpl currentUser) {
    //     Integer employeeOrAdminId = null;
    //     if (currentUser != null &&
    //             (currentUser.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_EMPLOYEE")
    //                     || a.getAuthority().equals("ROLE_ADMIN")))) {
    //         employeeOrAdminId = currentUser.getId();
    //     }

    //     BookingDto updatedBooking = bookingService.updateBookingStatus(bookingId, status, employeeOrAdminId);
    //     return ResponseEntity.ok(updatedBooking);
    // }

    // Note: Cancellation and Payment will have their own dedicated controllers and services.
    // For example, a POST to /api/bookings/{bookingId}/cancel or /api/bookings/{bookingId}/payment

    /**
     * 管理员手动清理过期预订
     */
    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/admin/clean-expired")
    public ResponseEntity<Map<String, String>> cleanExpiredBookings(
            @AuthenticationPrincipal UserDetailsImpl currentUser) {
        try {
            bookingService.processExpiredBookings();
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "message", "过期预订清理任务已完成"
            ));
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Map.of(
                    "status", "error",
                    "message", "过期预订清理失败: " + e.getMessage()
                ));
        }
    }
}